// @Author EthanScriptOn
// @Desc
package config_field_cache

import (
	"errors"
	"gitee.com/fatzeng/srf_switch_config/config_define"
)

type ExpansionFieldCache struct {
	ConfigInterface  interface{}
	ConfigFieldCache map[string]*FieldCache
}

func (e *ExpansionFieldCache) GetConfigInterface() interface{} {
	return e.ConfigInterface
}

func (e *ExpansionFieldCache) SetConfigInterface(configInterface interface{}) {
	e.ConfigInterface = configInterface
}

func (e *ExpansionFieldCache) GetConfigFieldCache() map[string]*FieldCache {
	return e.ConfigFieldCache
}

func (e *ExpansionFieldCache) SetConfigFieldCache(configFieldCache map[string]*FieldCache) {
	e.ConfigFieldCache = configFieldCache
}

func (e *ExpansionFieldCache) TransformTaggedInformation(beInjectedData map[string]interface{}, tagEnum string) (err error) {
	if len(e.ConfigFieldCache) <= 0 {
		return errors.New("config field cache is empty")
	}
	for _, fieldCachePtr := range e.ConfigFieldCache {
		fieldCache := fieldCachePtr
		conversion, err := e.TagListConversion(fieldCache.GetTagList())
		if err != nil {
			return
		}
		elemType, ok := conversion[tagEnum]
		if !ok {
			continue
		}
		singleBeInjectedData, ok := beInjectedData[string(elemType)]
		if !ok {
			continue
		}
		if err = fieldCache.FieldFillingWithInjectValue(singleBeInjectedData, tagEnum); err != nil {
			return
		}
	}
	return
}

func (e *ExpansionFieldCache) TagListConversion(tagList map[string]string) (map[string]config_define.NodeElemType, error) {
	if len(tagList) <= 0 {
		return nil, errors.New("tagList is empty")
	}
	conversionMap := make(map[string]config_define.NodeElemType)
	for key, val := range tagList {
		conversionMap[key] = config_define.NodeElemType(val)
	}
	return conversionMap, nil
}

func DisassemblyConfig(configInterface ...interface{}) ([]*ExpansionFieldCache, error) {
	allExpansionFieldCache := make([]*ExpansionFieldCache, 0)
	for _, cfg := range configInterface {
		expansionFieldCache, err := StructureExpansionFieldCache(cfg)
		if err != nil {
			return nil, err
		}
		allExpansionFieldCache = append(allExpansionFieldCache, expansionFieldCache)
	}
	return allExpansionFieldCache, nil
}

func StructureExpansionFieldCache(configInterface interface{}) (*ExpansionFieldCache, error) {
	expansionFieldCache := new(ExpansionFieldCache)
	expansionFieldCache.SetConfigInterface(configInterface)
	configFieldCache, err := buildFieldCache(configInterface)
	if err != nil {
		return nil, err
	}
	expansionFieldCache.SetConfigFieldCache(configFieldCache)
	return expansionFieldCache, nil
}

func buildFieldCache(configInterface interface{}) (map[string]*FieldCache, error) {
	if configInterface == nil {
		return nil, errors.New("configInterface is nil")
	}
	fieldCacheResult, err := GetFieldCache(configInterface)
	if err != nil {
		return nil, err
	}
	return fieldCacheResult, nil
}
